package org.example.Util;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import java.io.InputStream;
import java.util.Properties;

public class DataSourceUtil {
    private static final DataSource dataSource;

    static {
        try {
            // 加载配置文件
            Properties props = new Properties();
            try (InputStream in = DataSourceUtil.class.getClassLoader()
                    .getResourceAsStream("database.properties")) {
                if (in == null) {
                    throw new IllegalArgumentException("database.properties not found in classpath");
                }
                props.load(in);
            }

            // 配置HikariCP连接池
            HikariConfig config = new HikariConfig();
            config.setJdbcUrl(props.getProperty("url"));
            config.setUsername(props.getProperty("username"));
            config.setPassword(props.getProperty("password"));
            config.setDriverClassName(props.getProperty("driver"));

            // 优化连接池配置
            config.setMaximumPoolSize(20);          // 最大连接数
            config.setMinimumIdle(5);               // 最小空闲连接
            config.setConnectionTimeout(30000);     // 连接超时30秒
            config.setIdleTimeout(600000);          // 空闲连接超时10分钟
            config.setMaxLifetime(1800000);        // 连接最大存活时间30分钟
            config.setAutoCommit(true);            // 自动提交
            config.setPoolName("HikariPool-project"); // 连接池名称

            // 验证连接有效性
            config.setConnectionTestQuery("SELECT 1");
            config.addDataSourceProperty("cachePrepStmts", "true");
            config.addDataSourceProperty("prepStmtCacheSize", "250");
            config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

            dataSource = new HikariDataSource(config);
        } catch (Exception e) {
            throw new ExceptionInInitializerError("Failed to initialize HikariCP: " + e.getMessage());
        }
    }

    public static DataSource getDataSource() {
        return dataSource;
    }
}